package com.spzx.auth.service;

import com.spzx.auth.form.RegisterBody;
import com.spzx.common.core.constant.CacheConstants;
import com.spzx.common.core.constant.Constants;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.constant.UserConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.enums.UserStatus;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.core.text.Convert;
import com.spzx.common.core.utils.StringUtils;
import com.spzx.common.core.utils.ip.IpUtils;
import com.spzx.common.redis.service.RedisService;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.system.api.model.LoginUser;
import com.spzx.user.api.RemoteUserInfoService;
import com.spzx.user.api.domain.UpdateUserLogin;
import com.spzx.user.api.domain.UserInfo;
import jakarta.servlet.ServletException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

/**
 * projectName: spzx-parent
 *
 * @author: 王宝贵
 * time: 2024/10/12 20:24 周六
 * description:
 */
@Component
public class H5TokenService {

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Autowired
    private SysRecordLogService recordLogService;

    @Autowired
    private RemoteUserInfoService remoteUserInfoService;

    @Autowired
    private SysPasswordService passwordService;

    @Autowired
    private RedisService redisService;

    //用户注册
    public void register(RegisterBody registerBody) throws ServletException {

        String username = registerBody.getUsername();
        String nickName = registerBody.getNickName();
        String code = registerBody.getCode();
        String password = registerBody.getPassword();

        //1. 用户名或密码为空 错误
        if(username.isEmpty() || password.isEmpty()){
            throw  new ServiceException("用户名或者密码为空");
        }
        //账户长度必须是11个字符
        if(username.length()!=11){
            throw  new ServiceException("账号长度必须为11");
        }
        //验证码必须填写
        if(code.isEmpty()){
            throw  new ServiceException("验证码不能为空");
        }
        String redisCode = redisTemplate.opsForValue().get("phone:code:" + username);
        if(redisCode.isEmpty()){
            throw new ServiceException("验证码过期");
        }
        //验证码不正确
        if(!redisCode.equals(code)){
            throw  new ServiceException("验证码不正确");
        }

        //注册
        UserInfo userInfo = new UserInfo();

        userInfo.setUsername(username);
        nickName = StringUtils.isEmpty(nickName) ? username : nickName;
        userInfo.setNickName(nickName);
        userInfo.setPhone(username);
        //密码加密
         password = SecurityUtils.encryptPassword(password);
         userInfo.setPassword(password);
         //添加用户信息到数据库
        R<Boolean> register = remoteUserInfoService.register(userInfo, SecurityConstants.INNER);
        if(register.getCode() ==R.FAIL){
            //降级
            throw  new ServiceException("注册失败啦："+register.getMsg());
        }
        //记录日志（成功登录）
        recordLogService.recordLogininfor(username, Constants.REGISTER, "注册成功");
    }




    //用户登陆
    public LoginUser login(String username, String password) {
        // 用户名或密码为空 错误
        if(username.isEmpty() || password.isEmpty()){
            //记录日志
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写");
            throw  new ServiceException("用户名或者密码不能为空");
        }
        // 密码如果不在指定范围内 错误
        if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
        {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码不在指定范围");
            throw new ServiceException("用户密码不在指定范围");
        }
        // 用户名不在指定范围内 错误
        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                || username.length() > UserConstants.USERNAME_MAX_LENGTH)
        {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围");
            throw new ServiceException("用户名不在指定范围");
        }

        // TODO IP黑名单校验 11111111111
        String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST));
        if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
        {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾，访问IP已被列入系统黑名单");
            throw new ServiceException("很遗憾，访问IP已被列入系统黑名单");
        }

        // 查询用户信息
        R<UserInfo> userInfo = remoteUserInfoService.getUserInfo(username, SecurityConstants.INNER);
        //判断账号异常
        if(StringUtils.isNull(userInfo) || StringUtils.isNull(userInfo.getData())){
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登陆用户不存在");
            throw new ServiceException("登陆用户不存在："+username);
        }
        if (userInfo.getCode() ==R.FAIL){
            throw  new ServiceException("触发降级处理啦:"+userInfo.getMsg());
        }
        //模块转变
        LoginUser loginUser = new LoginUser();
        UserInfo userInfoData = userInfo.getData();
        loginUser.setUserid(userInfoData.getId());
        loginUser.setUsername(userInfoData.getUsername());
        loginUser.setPassword(userInfoData.getPassword());
        //状态
        loginUser.setStatus(userInfoData.getStatus()+"");
        //验证状态 222222222222222
        if (UserStatus.DISABLE.getCode().equals(userInfoData.getStatus()))
        {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用，请联系管理员");
            throw new ServiceException("对不起，您的账号：" + username + " 已停用");
        }
        //密码的锁定次数 3333333333
        passwordService.validate(loginUser, password);
        //日志 44444444444
        recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");


        //更新登录信息
        UpdateUserLogin updateUserLogin = new UpdateUserLogin();
        updateUserLogin.setUserId(userInfoData.getId());
        updateUserLogin.setLastLoginIp(userInfoData.getLastLoginIp());
        updateUserLogin.setLastLoginTime(userInfoData.getLastLoginTime());
        remoteUserInfoService.updateUserLogin(updateUserLogin,SecurityConstants.INNER);
        System.out.println("登陆成功");
        return loginUser;
    }
}